﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Globalization;
using System.Collections;
using AdmLaboratorios.DTO;
using AdmLaboratorios.Business;

namespace AdmLaboratorios
{
    public static class FormsHelper
    {
        public const string formatoMonto = "#0.00";                 //NO CAMBIAR.
        public const string formatoMontoConSimbolo = "$ #0.00";     //NO CAMBIAR.
        public const string formatoFecha = "dd/MM/yyyy";            //NO CAMBIAR.

        private static dsGridsConfig.dtGridsConfigDataTable gridsConfig;
        private const string gridsConfigFile = "GridsConfig.xml";
        private const string opcionesFile = "Opciones.xml";

        private static List<GrillaColumnaDTO> grillaColumnas;

        internal static void RefrescarColumnasGrilla()
        {
            grillaColumnas = BusinessHelper.GetGrillaColumnas();
        }

        #region Grids

        public static void InicializarColumnas(ref DataGridView dg, params string[] Columnas)
        {
            dg.AutoGenerateColumns = false;
            dg.Columns.Clear();

            for (int i = 0; i < Columnas.Length; i = i + 3)
            {
                dg.Columns.Add(Columnas[i + 1], Columnas[i + 2]);
                dg.Columns[Columnas[i + 1]].DataPropertyName = Columnas[i + 1];
            }
        }

        public static void InicializarColumnas(ref DataGridView dg, params DataGridViewColumn[] Columnas)
        {
            dg.AutoGenerateColumns = false;
            dg.Columns.Clear();

            for (int i = 0; i < Columnas.Length; i++)
            {
                dg.Columns.Add(Columnas[i]);
            }
        }

        public static void CargarColumnasGrilla(Form f)
        {
            foreach (Control c in f.Controls)
            {
                CargarColumnasGrilla(f, c);
            }
        }

        public static void CargarColumnasGrilla(Form f, Control c)
        {
            if (c.GetType() == typeof(DataGridView))
                CargarColumnasGrilla(f, (DataGridView)c);
            else if (c.GetType() == typeof(ListView))
                CargarColumnasListView(f, (ListView)c);
            else
                foreach (Control cChild in c.Controls)
                    CargarColumnasGrilla(f, cChild);
        }

        public static void CargarColumnasGrilla(Form f, DataGridView dg)
        {
            try
            {
                //Manejo el visible/invisible de las columnas.
                dg.DataSourceChanged += new EventHandler(dg_DataSourceChanged);
                dg.ColumnHeaderMouseClick += new DataGridViewCellMouseEventHandler(dg_ColumnHeaderMouseClick);
                GrillaMostrarUOcultarColumnas(dg);

                if (gridsConfig == null)
                {
                    gridsConfig = new dsGridsConfig.dtGridsConfigDataTable();
                    gridsConfig.Clear();
                    gridsConfig.ReadXml(gridsConfigFile);
                }

                string filtro = string.Format("Formulario = '{0}' AND Grilla = '{1}'", f.Name, dg.Name);

                foreach (System.Data.DataRow dr in gridsConfig.Select(filtro))
                {
                    //Si la columna del config, existe en la grilla, le updateo el tamaño, visible, etc.
                    if (dg.Columns.Contains((String)dr["Columna"]))
                    {
                        dg.Columns[(String)dr["Columna"]].Width = Convert.ToInt32(dr["Ancho"]);
                        dg.Columns[(String)dr["Columna"]].DisplayIndex = Convert.ToInt32(dr["Posicion"]);
                    }
                }
            }
            catch (Exception)
            {
            }
        }

        public static void GrillaMostrarUOcultarColumnas(DataGridView gv)
        {
            try
            {
                string formName = gv.FindForm().Name;


                if (grillaColumnas == null)
                    grillaColumnas = BusinessHelper.GetGrillaColumnas();

                var columnas = grillaColumnas.FindAll(x => x.Formulario == formName && x.Grilla == gv.Name);

                foreach (DataGridViewColumn column in gv.Columns)
                {
                    var definition = columnas.Find(x => x.Columna == column.Name);
                    if (definition != null)
                    {
                        column.Visible = definition.Visible;
                    }
                }
            }
            catch (Exception)
            {
            }
        }

        static void dg_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (BusinessHelper.Usuario.EsAdministrador)
                {
                    using (frmGridCustomizer f = new frmGridCustomizer())
                    {
                        FormsHelper.CargarColumnasGrilla(f);
                        f.Inicializar((DataGridView)sender);
                        f.ShowDialog();
                    }
                }
            }
        }

        static void dg_DataSourceChanged(object sender, EventArgs e)
        {
            DataGridView gv = (DataGridView)sender;
            GrillaMostrarUOcultarColumnas(gv);
        }

        public static void CargarColumnasListView(Form f, ListView lv)
        {
            try
            {
                if (gridsConfig == null)
                {
                    gridsConfig = new dsGridsConfig.dtGridsConfigDataTable();
                    gridsConfig.Clear();
                    gridsConfig.ReadXml(gridsConfigFile);
                }

                string filtro = string.Format("Formulario = '{0}' AND Grilla = '{1}'", f.Name, lv.Name);

                foreach (System.Data.DataRow dr in gridsConfig.Select(filtro))
                {
                    //Si la columna del config, existe en la grilla, le updateo el tamaño, visible, etc.
                    foreach (ColumnHeader c in lv.Columns)
                    {
                        if (c.Text == (String)dr["Columna"])
                        {
                            c.Width = Convert.ToInt32(dr["Ancho"]);
                            c.DisplayIndex = Convert.ToInt32(dr["Posicion"]);
                            break;
                        }
                    }
                }
            }
            catch (Exception)
            {
            }
        }

        public static void GuardarColumnasGrilla(Form f)
        {
            foreach (Control c in f.Controls)
            {
                GuardarColumnasGrilla(f, c);
            }
        }

        public static void GuardarColumnasGrilla(Form f, Control c)
        {
            if (c.GetType() == typeof(DataGridView))
                GuardarColumnasGrilla(f, (DataGridView)c);
            else if (c.GetType() == typeof(ListView))
                GuardarColumnasListView(f, (ListView)c);
            else
                foreach (Control cChild in c.Controls)
                {
                    GuardarColumnasGrilla(f, cChild);
                }
        }

        public static void GuardarColumnasGrilla(Form f, DataGridView dg)
        {
            try
            {
                try
                {
                    if (gridsConfig == null)
                    {
                        gridsConfig = new dsGridsConfig.dtGridsConfigDataTable();
                        gridsConfig.Clear();
                        gridsConfig.ReadXml(gridsConfigFile);
                    }

                    string filtro = string.Format("Formulario = '{0}' AND Grilla = '{1}'", f.Name, dg.Name);

                    //Elimino todos los registros relacionados a esta grilla.
                    foreach (System.Data.DataRow dr in gridsConfig.Select(filtro))
                    {
                        dr.Delete();
                    }
                }
                catch (Exception)
                {
                }

                //Creo los nuevos registros que necesito.
                foreach (DataGridViewColumn c in dg.Columns)
                {
                    gridsConfig.AdddtGridsConfigRow(f.Name, dg.Name, c.Name, c.Width, c.DisplayIndex);
                }

                gridsConfig.AcceptChanges();
                gridsConfig.WriteXml(gridsConfigFile);
            }
            catch (Exception)
            {
            }
        }

        public static void GuardarColumnasListView(Form f, ListView lv)
        {
            try
            {
                try
                {
                    if (gridsConfig == null)
                    {
                        gridsConfig = new dsGridsConfig.dtGridsConfigDataTable();
                        gridsConfig.Clear();
                        gridsConfig.ReadXml(gridsConfigFile);
                    }

                    string filtro = string.Format("Formulario = '{0}' AND Grilla = '{1}'", f.Name, lv.Name);

                    //Elimino todos los registros relacionados a esta grilla.
                    foreach (System.Data.DataRow dr in gridsConfig.Select(filtro))
                    {
                        dr.Delete();
                    }
                }
                catch (Exception)
                {
                }

                //Creo los nuevos registros que necesito.
                foreach (ColumnHeader c in lv.Columns)
                {
                    gridsConfig.AdddtGridsConfigRow(f.Name, lv.Name, c.Text, c.Width, c.DisplayIndex);
                }

                gridsConfig.AcceptChanges();
                gridsConfig.WriteXml(gridsConfigFile);
            }
            catch (Exception)
            {
            }
        }

        internal static void PintarBotones(DataGridViewCellPaintingEventArgs e, DataGridView gv, ImageList ilBotones)
        {
            DataGridViewButtonCell celBoton;

            if (e.ColumnIndex >= 0 && gv.Columns[e.ColumnIndex].Name == "cEdit" && e.RowIndex >= 0)
            {
                e.Paint(e.CellBounds, DataGridViewPaintParts.All);

                celBoton = gv.Rows[e.RowIndex].Cells["cEdit"] as DataGridViewButtonCell;
                if (ilBotones.Images.ContainsKey("Edit"))
                    e.Graphics.DrawImage(ilBotones.Images["Edit"], e.CellBounds.Left + 3, e.CellBounds.Top + 3);
                else
                    e.Graphics.DrawImage(ilBotones.Images[0], e.CellBounds.Left + 3, e.CellBounds.Top + 3);

                //gv.Rows[e.RowIndex].Height = 26;
                //gv.Columns[e.ColumnIndex].Width = 26;

                e.Handled = true;
            }
            else if (e.ColumnIndex >= 0 && gv.Columns[e.ColumnIndex].Name == "cDelete" && e.RowIndex >= 0)
            {
                e.Paint(e.CellBounds, DataGridViewPaintParts.All);

                celBoton = gv.Rows[e.RowIndex].Cells["cDelete"] as DataGridViewButtonCell;
                if (ilBotones.Images.ContainsKey("Delete"))
                    e.Graphics.DrawImage(ilBotones.Images["Delete"], e.CellBounds.Left + 3, e.CellBounds.Top + 3);
                else
                    e.Graphics.DrawImage(ilBotones.Images[1], e.CellBounds.Left + 3, e.CellBounds.Top + 3);

                //gv.Rows[e.RowIndex].Height = 26;
                //gv.Columns[e.ColumnIndex].Width = 26;

                e.Handled = true;
            }
            else if (e.ColumnIndex >= 0 && gv.Columns[e.ColumnIndex].Name == "cSave" && e.RowIndex >= 0)
            {
                e.Paint(e.CellBounds, DataGridViewPaintParts.All);

                celBoton = gv.Rows[e.RowIndex].Cells["cSave"] as DataGridViewButtonCell;
                if (ilBotones.Images.ContainsKey("Save"))
                    e.Graphics.DrawImage(ilBotones.Images["Save"], e.CellBounds.Left + 3, e.CellBounds.Top + 3);
                else
                    e.Graphics.DrawImage(ilBotones.Images[2], e.CellBounds.Left + 3, e.CellBounds.Top + 3);

                //gv.Rows[e.RowIndex].Height = 26;
                //gv.Columns[e.ColumnIndex].Width = 26;

                e.Handled = true;
            }
            else if (e.ColumnIndex >= 0 && gv.Columns[e.ColumnIndex].Name == "cSearch" && e.RowIndex >= 0)
            {
                e.Paint(e.CellBounds, DataGridViewPaintParts.All);

                celBoton = gv.Rows[e.RowIndex].Cells["cSearch"] as DataGridViewButtonCell;
                if (ilBotones.Images.ContainsKey("Search"))
                    e.Graphics.DrawImage(ilBotones.Images["Search"], e.CellBounds.Left + 3, e.CellBounds.Top + 3);
                else
                    e.Graphics.DrawImage(ilBotones.Images[3], e.CellBounds.Left + 3, e.CellBounds.Top + 3);

                //gv.Rows[e.RowIndex].Height = 26;
                //gv.Columns[e.ColumnIndex].Width = 26;

                e.Handled = true;
            }
            else if (e.ColumnIndex >= 0 && gv.Columns[e.ColumnIndex].Name == "cCommit" && e.RowIndex >= 0)
            {
                e.Paint(e.CellBounds, DataGridViewPaintParts.All);

                celBoton = gv.Rows[e.RowIndex].Cells["cCommit"] as DataGridViewButtonCell;
                if (ilBotones.Images.ContainsKey("Commit"))
                    e.Graphics.DrawImage(ilBotones.Images["Commit"], e.CellBounds.Left + 3, e.CellBounds.Top + 3);
                else
                    e.Graphics.DrawImage(ilBotones.Images[4], e.CellBounds.Left + 3, e.CellBounds.Top + 3);

                //gv.Rows[e.RowIndex].Height = 26;
                //gv.Columns[e.ColumnIndex].Width = 26;

                e.Handled = true;
            }
            else if (e.ColumnIndex >= 0 && gv.Columns[e.ColumnIndex].Name == "cRollback" && e.RowIndex >= 0)
            {
                e.Paint(e.CellBounds, DataGridViewPaintParts.All);

                celBoton = gv.Rows[e.RowIndex].Cells["cRollback"] as DataGridViewButtonCell;
                if (ilBotones.Images.ContainsKey("Rollback"))
                    e.Graphics.DrawImage(ilBotones.Images["Rollback"], e.CellBounds.Left + 3, e.CellBounds.Top + 3);
                else
                    e.Graphics.DrawImage(ilBotones.Images[5], e.CellBounds.Left + 3, e.CellBounds.Top + 3);

                //gv.Rows[e.RowIndex].Height = 26;
                //gv.Columns[e.ColumnIndex].Width = 26;

                e.Handled = true;
            }
        }

        #endregion

        #region Numbers

        public static decimal StN(string numero)
        {
            //Obtengo la cultura 'regional' actual.
            System.Globalization.CultureInfo c = System.Globalization.CultureInfo.CurrentCulture;

            if (numero.Trim() == "")
                return 0;

            decimal resultado;

            //Reemplazo el separador de grupos por el separador de miles.
            numero = numero.Replace(c.NumberFormat.NumberGroupSeparator, c.NumberFormat.NumberDecimalSeparator);

            if (Decimal.TryParse(numero, out resultado))
                return resultado;
            else
                return 0;
        }

        public static decimal StN(object numero)
        {
            //Obtengo la cultura 'regional' actual.
            System.Globalization.CultureInfo c = System.Globalization.CultureInfo.CurrentCulture;

            if (numero == null)
                return 0;

            if (numero.ToString().Trim() == "")
                return 0;

            decimal resultado;

            //Reemplazo el separador de grupos por el separador de miles.
            numero = numero.ToString().Replace(c.NumberFormat.NumberGroupSeparator, c.NumberFormat.NumberDecimalSeparator);

            if (Decimal.TryParse(numero.ToString(), out resultado))
                return resultado;
            else
                return 0;
        }

        #endregion

        #region MsgBoxes

        /// <summary>
        /// Muestra un MessageBox avisando que existen campos obligatorios sin cargar.
        /// </summary>
        public static void MsgErrorValidacion()
        {
            System.Windows.Forms.MessageBox.Show(
                "Hay campos obligatorios sin cargar."
                , "Error de Validación"
                , System.Windows.Forms.MessageBoxButtons.OK
                , System.Windows.Forms.MessageBoxIcon.Exclamation);
        }

        public static void MsgErrorEnUso()
        {
            System.Windows.Forms.MessageBox.Show(
                "No puede eliminar esta entidad, debido a que ya ha sido utilizada en el sistema."
                , "Imposible Eliminar"
                , System.Windows.Forms.MessageBoxButtons.OK
                , System.Windows.Forms.MessageBoxIcon.Error);
        }

        public static void MsgGuardadoOk()
        {
            System.Windows.Forms.MessageBox.Show(
                "Los cambios se guardaron correctamente."
                , "Operación Completada"
                , System.Windows.Forms.MessageBoxButtons.OK
                , System.Windows.Forms.MessageBoxIcon.Asterisk);
        }

        public static void MsgSinDatosOk()
        {
            System.Windows.Forms.MessageBox.Show(
                "No se han encontrado datos."
                , "Operación Cancelada"
                , System.Windows.Forms.MessageBoxButtons.OK
                , System.Windows.Forms.MessageBoxIcon.Asterisk);
        }

        public static void MsgErrorInesperado()
        {
            System.Windows.Forms.MessageBox.Show(
                "Ocurrió un Error Inesperado. Por favor, cierre la ventana, e intente la operación nuevamente."
                , "Error Inesperado"
                , System.Windows.Forms.MessageBoxButtons.OK
                , System.Windows.Forms.MessageBoxIcon.Error);
        }

        public static void MsgErrorInesperado(Exception ex)
        {
            GuardarLog(ex);

            System.Windows.Forms.MessageBox.Show(
                "Ocurrió un Error Inesperado. Por favor, cierre la ventana, e intente la operación nuevamente."
                , "Error Inesperado"
                , System.Windows.Forms.MessageBoxButtons.OK
                , System.Windows.Forms.MessageBoxIcon.Error);
        }

        internal static void MsgNoHayUnElementoSeleccionado()
        {
            MessageBox.Show("No existe ningún elemento seleccionado.",
                "No hay un elemento seleccionado", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        internal static void MsgSinPermisos()
        {
            MessageBox.Show("Ud. no puede llevar a cabo esta operación, ya que no cuenta con el nivel de permisos necesarios.",
                "No tiene permisos para realizar esta operación", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }

        #endregion

        #region Logging

        static void GuardarLog(Exception ex)
        {
            try
            {
                string fileName = Environment.CurrentDirectory + @"\Err.log";
                string info = "";

                info = GetExMsg(ex);

                System.IO.File.AppendAllText(fileName, info, System.Text.Encoding.Default);

                try
                {
                    BusinessHelper.Log(info);
                    //Logs.Log(LogDTO.eAcciones.Excepcion, info, 0, "", "", "", "");
                }
                catch (Exception ex2)
                {
                    MessageBox.Show("Error Guardando Log en DB: " + ex2.Message);
                }
            }
            catch (Exception ex3)
            {
                MessageBox.Show("Error Generando Log: " + ex3.Message);
            }
        }

        static string GetExMsg(Exception ex)
        {
            if (ex.InnerException != null)
                return "\n\r" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " | " + ex.Message + GetExMsg(ex.InnerException);
            else
                return "\n\r" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " | " + ex.Message;
        }

        #endregion

        #region Performance

        public static void cWait()
        {
            FormsFactory.MDI.Cursor = Cursors.WaitCursor;
        }

        public static void cDefault()
        {
            FormsFactory.MDI.Cursor = Cursors.Default;
        }

        public static Form GetForm<T>()
        {
            foreach (Form f in FormsFactory.MDI.MdiChildren)
            {
                if (f.GetType() == typeof(T))
                {
                    return f;
                }
            }
            return null;
        }

        //public static void MsgEst(string mensaje)
        //{
        //    //FormsFactory.MDI.lblEstado.Text = "Estado: " + mensaje;
        //}

        #endregion

        #region ActiveX
        public static void OcxRegister(string activeXName)
        {
            string aux = Application.StartupPath + "\\ezDICOMax.ocx /s";
            System.Diagnostics.Process.Start("regsvr32", aux);
        }
        #endregion

        #region General Functions

        public static void FillCombo(Type enumeration, ComboBox comboBox)
        {
            comboBox.DataSource = null;
            comboBox.Items.Clear();
            foreach (var item in Enum.GetNames(enumeration))
                comboBox.Items.Add(item);
        }

        public static void FillCombo(List<string> elementos, ComboBox comboBox)
        {
            comboBox.DataSource = null;
            comboBox.Items.Clear();
            foreach (var item in elementos)
                comboBox.Items.Add(item);
        }

        internal static byte[] ImageToBytes(Image img)
        {
            try
            {
                string sTemp = Path.GetTempFileName();
                FileStream fs = new FileStream(sTemp, FileMode.OpenOrCreate, FileAccess.ReadWrite);

                img.Save(fs, System.Drawing.Imaging.ImageFormat.Jpeg);
                fs.Position = 0;

                int imgLength = Convert.ToInt32(fs.Length);
                byte[] bytes = new byte[imgLength];

                fs.Read(bytes, 0, imgLength);
                fs.Close();

                return bytes;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        internal static Image BytesToImage(byte[] bytes)
        {
            if (bytes == null) return null;

            MemoryStream ms = new MemoryStream(bytes);
            Bitmap bm = null;

            try
            {
                bm = new Bitmap(ms);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
            return bm;
        }

        internal static string GetColorName(Color color)
        {
            try
            {
                if (color.IsNamedColor)
                    return color.Name;
                else
                    return "#" + color.Name;
            }
            catch (Exception)
            {
                return "White";
            }
        }

        internal static Color GetColor(string colorNameOrCode)
        {
            try
            {
                ColorConverter cc = new ColorConverter();
                Color c = (Color)cc.ConvertFromString(colorNameOrCode);
                return c;
            }
            catch (Exception)
            {
                return Color.White;
            }
        }

        internal static Version GetRunningVersion()
        {
            if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
                return System.Deployment.Application.ApplicationDeployment.CurrentDeployment.CurrentVersion;
            else
                return Assembly.GetExecutingAssembly().GetName().Version;
        }
        
        public static string RemoveDiacritics(this string stIn)
        {
            string stFormD = stIn.Normalize(NormalizationForm.FormD);
            StringBuilder sb = new StringBuilder();

            for (int ich = 0; ich < stFormD.Length; ich++)
            {
                UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]);
                if (uc != UnicodeCategory.NonSpacingMark)
                {
                    sb.Append(stFormD[ich]);
                }
            }

            return (sb.ToString().Normalize(NormalizationForm.FormC));
        }

        public static bool Contains(this string source, string toCheck, StringComparison comp)
        {
            return source.IndexOf(toCheck, comp) >= 0;
        }

        public static void CargarCombo(ref System.Windows.Forms.ComboBox comboBox, IList datos)
        {
            comboBox.DisplayMember = "Desc";
            comboBox.ValueMember = "Id";
            comboBox.DataSource = datos;
        }

        #endregion
    }    
    
    //public struct GridInfo
    //{
    //    public DataGridView MasterGrid;
    //    public DataGridView DetailGrid;
    //    public string ActualFilter;
    //    public SplitterPanel ContainerPanel;
    //}
}
